package com.wz.dhs.utils;

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @description: Redis相关工具类
 * @param:
 * @return:
 * @author: xia
 * @time: 2021/12/2 18:01
 */
@Component
@AllArgsConstructor
public class RedisUtils implements ApplicationContextAware {

    private static RedisTemplate<String,Object> redisTemplate;

    private static RedisConnectionFactory redisConnectionFactory;

    /**
     * @description: 自增ID
     * @param:
     * @return:
     * @author: xia
     * @time: 2021/12/2 18:10
     */
    public static Long generateNum(String key){
        RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, redisConnectionFactory);
        long timeMillis = System.currentTimeMillis();
        return redisAtomicLong.incrementAndGet()+timeMillis;
    }


     /**
       * @Description: hash value自增加一并设置有效期
       * @author xia
       * @date 2024/1/7
       */
    public static Long incrHashWithTime(String name,String key){
        Long increment = redisTemplate.opsForHash().increment(name, key, 1);
        if(increment == 1){
            redisTemplate.expire(name,1,TimeUnit.DAYS);
        }
        return increment;
    }

    /**
     * @description: 获取分布式锁
     * @param:
     * @return:
     * @author: xia
     * @time: 2021/10/21 10:22
     */
    public static Boolean getLock(String key, String value, long time, TimeUnit timeUnit){
        return redisTemplate.opsForValue().setIfAbsent(key,value,time,timeUnit);
    }

    /**
     * @description: 释放锁
     * @param:
     * @return:
     * @author: xia
     * @time: 2021/10/21 10:35
     */
    public static void releaseLock(String key,String value){
        String data = (String)redisTemplate.opsForValue().get(key);
        if(data.equals(value)){
            redisTemplate.delete(key);
        }
    }

    public static void setExpireTime(String key,TimeUnit timeUnit,Long time){
        redisTemplate.expire(key,time,timeUnit);
    }

    /**
     * 获取值序列化
     */
    public static <T> T getValue(String key, Class<T> data) {
        Object result = redisTemplate.opsForValue().get(key);
        return JSONUtils.paraseJson(JSON.toJSONString(result), data);
    }


    /**
     * @description: 判断是否有key
     * @param:
     * @return:
     * @author: xia
     * @time: 2022/2/20 10:30
     */
    public static Boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    public static void delKey(String key){
        redisTemplate.delete(key);
    }

    /**
     * 设置值
     */
    public static void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 设置值有过期时间
     */
    public static void setValueWithExpire(String key, Object value, TimeUnit timeUnit, Long time) {
        redisTemplate.opsForValue().set(key, value, time, timeUnit);
    }

    /**
     * 设置key，如果有返回true，没有返回false
     */
    public static Boolean setIfAbsent(String key,Object value,TimeUnit timeUnit,Long time){
        return redisTemplate.opsForValue().setIfAbsent(key,value,time,timeUnit);
    }

    /**
     * 自减指定位数
     **/
    public void decryBy(String key,long value){
        redisTemplate.opsForValue().decrement(key, value);
    }

    /**
     * 获取值
     */
    public static String getValueOfString(String key) {
        return (String) redisTemplate.opsForValue().get(key);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        redisTemplate = applicationContext.getBean("customRedisTemplate",RedisTemplate.class);
        redisConnectionFactory = applicationContext.getBean(RedisConnectionFactory.class);
    }
}
